/*
* Copyright (C) 2021 ~ 2022 Uniontech Technology Co., Ltd.
*
* Author:      zhangbingyi <zhangbingyi@uniontech.com>
*
* Maintainer:  zhangbingyi <zhangbingyi@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "common.h"
#include "common/usbmanagercomm.h"
#include "usbpolicykithelper.h"
#include "usbimportandexportjob.h"

#include <QWidget>
#include <QThread>
#include <QSettings>

class DBusInvokerInterface;
class SettingsInvokerInterface;

namespace def {
class SystemSettings;
}

using namespace def;


class USBStorageSecurityModel : public QObject
{
    Q_OBJECT
public:
    explicit USBStorageSecurityModel(QObject *parent = nullptr);
    ~USBStorageSecurityModel();

    bool isInUDCPDomain();

    inline QList<USBConnectionInfo> &usbConnectionInfoLst()
    {
        return m_usbConnectionInfoLst;
    }

    inline QList<USBConnectionInfo> &usbConnectionWhiteLst()
    {
        return m_usbWhitelistInfoLst;
    }

    int getGlobalPermMode();

    // 清除连接记录
    Q_SLOT void asyncClearUsbConnectionLog();

    // 判断该USB设备是否已存入在白名单列表中
    bool isUsbDeviceInWhiteList(const QString &serial, const QString &vendor, const QString &product);

    // 设置界面是否启用状态
    inline bool getUIEnableStatus() const { return m_uiEnableStatus; }
    inline void setUIEnableStatus(bool enable);

    // 调取某一个USB设备详情信息
    void asyncReadUSBDetails(const USBConnectionInfo &info);

    // USB设备详情页 导出功能相关 -- 调取某USB设备全部连接记录日志
    void asyncGetOneDevAllConnList(const QString &path, const USBConnectionInfo &info);

    // USB连接记录 导出全部设备全部连接记录
    void asyncGetAllUSBStorageConnList(const QString &path);

    // 显示悬浮弹框
    void showFloatMsg(QWidget *widget, const QString &iconPath, const QString &msg, int dura = 3000);

private:
    // 加载配置
    void loadConfig();
    // 读取usb连接记录
    void asyncReadNeedShowRecords();
    // 读取usb连接白名单
    void asyncReadConnectionWhiteLst();
    // clean超过30天
    void cleanUsbConnectionLog();
    // 新连接USB的Name改变，更新白名单列表Name信息
    void updateNameAndSizeInWhitelist(const USBConnectionInfo &info);

Q_SIGNALS:
    // 发送需要添加到表格的信息
    void sendUsbConnectionLogInfo(const USBConnectionInfo &info);
    // 新连接的USB名称有改变，则改变白名单列表Name显示
    void notifyUpdateNameAndSizeInWhitelist(const USBConnectionInfo &info, const QString &name, qint64 size);

    // 发送USB设备详情信息
    void sendUSBDetails(const USBConnectionInfoList &list);

    // 请求确认选择usb限制模式
    void requestConfirmSelectLimitationMode(int limitMode);
    // 通知去改变usb限制模式
    void notifyChangeLimitationMode(int mode);

    // 请求确认添加到白名单
    void requestConfirmAddUsbConnectionWhiteLst(const USBConnectionInfo &info);
    // 请求授权改变白名单设备权限
    void requestAuthorizeChangeDevPerm(const USBConnectionInfo &info);

    // 发送需要显示的连接记录
    void sendNeedShowRecords(const USBConnectionInfoList &list);

    // 请求确认清除usb连接记录
    void requestConfirmClearUsbConnectionLog();

    // 请求确认导入白名单
    void requestConfirmImportWhitelist();

    // 权限校验完成
    void checkAuthorizationFinished();

    // 发送全部白名单列表信息
    void sendAllWhitelist(const USBConnectionInfoList &list);

    // 通知USB白名单移除完成
    void removeWhitelistFinished(const USBConnectionInfo &info);

    // 通知 成功添加到白名单列表中
    void addUSBWhitelistFinished(const USBConnectionInfo &info);
    void operateStorageWhitelistFinished(int opType, const USBConnectionInfo &info);
    // 通知 展示提示弹窗 白名单添加成功后提示
    void notifyShowAddWhitelistTip();

    // 通知 成功批量 添加到白名单列表中
    void addBatchUSBWhitelistBatchFinished(const USBConnectionInfoList &list);

    // 通知 成功批量 修改到白名单列表中
    void modifyBatchUSBWhitelistBatchFinished(const USBConnectionInfoList &list);
    // 批量导入白名单完成
    void importBatchStorageWhitelistFinished(const USBConnectionInfoList &list);

    // 通知 成功清除 所有设备所有连接记录
    void clearAllDevRecordsFinished();

    // 发送白名单下载模板信号 --NEW
    void notifyExportWhitelistTemplate(const QString &path);

    // 发送导入白名单信号 --NEW
    void notifyImportUSBWhitelist(const QString &path);

    // 发送导出全部设备的连接记录 -- NEW
    void notifyExportAllConnectionRecords(const QString &path, const USBConnectionInfoList &list);

    // 发送导出某一设备的全部连接记录 -- NEW
    void notifyExportOneDveConnectionRecords(const QString &path, const USBConnectionInfoList &list);

    // 通知白名单界面刷新
    void notifyWhitelistDlgUpdate();
public slots:
    void sendRequestConfirmAddUsbConnectionWhiteLst(const USBConnectionInfo &info) {emit requestConfirmAddUsbConnectionWhiteLst(info);}
    void sendRequestConfirmClearUsbConnectionLog() {emit requestConfirmClearUsbConnectionLog();}
    void sendRequestConfirmSelectLimitationMode(int limitMode) {emit requestConfirmSelectLimitationMode(limitMode);}
public Q_SLOTS:
    void asyncSelectLimitationMode(int mode);
    // 当接收到设备接入的信息
    void onReceiveUsbInfo(const USBConnectionInfo &info);

    // 接收到全局USB管控权限模式
    void onSetGlobalPermModeFininshed(int mode);

    // 获取链接记录
    void onRecvNeedShowRecords(const USBConnectionInfoList &list);

    // 获取白名单记录
    void onRecvWhitelist(const USBConnectionInfoList &list);
    // 调用DBUS 对白名单 进行增删
    void asyncOperateStorageWhitelist(int type, const USBConnectionInfo &info);
    // 接收 白名单 批量设置信号  调用DBUS
    void asyncOperateBatchStorageWhitelist(int type, const USBConnectionInfoList &list);
    // 批量导入白名单
    void asyncImportBatchStorageWhitelist(const USBConnectionInfoList &list);

    // 白名单模板下载
    void exportWhitelistTemplate();
    // 显示导入白名单文件选择器
    void showImportWhitelistDlg();

    // 白名单校验失败
    void onUSBWhitelistInfoVerifyFailed(int row, const QString &name);

    // 白名单校验失败 其他场景
    void onImportWhitelistFailed();

    // 白名单导入成功
    void onImportBatchStorageWhitelistFinished(const USBConnectionInfoList &list);

    // 接收到DBus 白名单操作状态限制结果
    void onOperateStorageWhitelistFinished(int type, const USBConnectionInfo &info);
    // 接收到DBus 白名单批量操作状态结果
    void onOperateBatchStorageWhitelistFinished(int type, const USBConnectionInfoList &list);

    // 接收到Dbus USB清除连接记录操作结果
    void onClearAllUSBStorageConnLogFinished();

    // 接收到DBus USB详情列表数据
    void onRecvUSBDetails(const USBConnectionInfoList &list);

    // 接收到导出某一设备详情日志的全部数据 并执行导出操作
    void onRecvOneDevAllConnList(const USBConnectionInfoList &list);

    // 接收到导出全部设备全部连接记录  并执行导出操作
    void onRecvAllDevAllConnList(const USBConnectionInfoList &list);

    void notifyAddUsbConnectionWhiteLst(const USBConnectionInfo &info);
    void notifyChangeDevPerm(const USBConnectionInfo &info);
    void emitCheckAuthorizationFinished();
    void exportOneDevConnectionRecordFinished();
    void onUSBWhitelistInfoVerifyFailedHelp(int index, QString);
private:
    // 系统配置
    SystemSettings *m_systemSettings;
    //初始配置
    int m_globalPermMode; // USB存储设备连接模式
    bool m_uiEnableStatus; // 界面启用状态

    // USB连接记录
    QList<USBConnectionInfo> m_usbConnectionInfoLst;
    // USB白名单列表
    QList<USBConnectionInfo> m_usbWhitelistInfoLst;

    DBusInvokerInterface *m_usbManagerInvokerInter;
    DBusInvokerInterface *m_monitorNetFlowInvokerInter;
    QThread m_polKitHelperThread;
    QThread m_jobThread;
    USBPolicyKitHelper *m_policyKitHelper;
    USBImportAndExportJob *m_importAndExportJob;

    QString m_detailsSavePath; // 某一设备详情导出路径
    QString m_allConnSavePath; // 全部连接记录导出路径
};
